package dao

import (
	"context"
	"wxpay/internal/model"
	"wxpay/pkg/merrors"

	"github.com/nsqio/go-nsq"
	"github.com/patrickmn/go-cache"
	"gorm.io/gorm"
)

type Applyment interface {
	// 创建/保存进件申请
	Save(ctx context.Context, tx *gorm.DB, m *model.Applyment) error
	// 查询进件申请
	QueryByApplyNo(ctx context.Context, db *gorm.DB, applyNo string) (*model.Applyment, error)
	// 查询进件申请（根据业务申请编号）
	QueryByBizApplyNo(ctx context.Context, db *gorm.DB, bizApplyNo string) (*model.Applyment, error)
}

type ApplymentRepo struct {
	*gorm.DB
	producer *nsq.Producer
	cache    *cache.Cache
}

func (r *ApplymentRepo) QueryByBizApplyNo(_ context.Context, db *gorm.DB, bizApplyNo string) (*model.Applyment, error) {
	const op merrors.Op = "ApplymentRepo.QueryByBizApplyNo"
	res := model.Applyment{}
	if err := db.Model(&model.Applyment{}).Where("biz_apply_no = ?", bizApplyNo).First(&res).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, merrors.E(op, merrors.NotExist, merrors.ErrNotFound, err)
		} else {
			return nil, merrors.E(op, merrors.DBError, merrors.ErrInternal, err)
		}
	}
	return &res, nil
}

func NewApplymentRepo(d *gorm.DB, p *nsq.Producer, c *cache.Cache) *ApplymentRepo {
	return &ApplymentRepo{
		DB:       d,
		producer: p,
		cache:    c,
	}
}

// 新建进件申请
func (r *ApplymentRepo) Save(_ context.Context, tx *gorm.DB, m *model.Applyment) error {
	const op merrors.Op = "ApplymentRepo.Save"
	if err := tx.Save(m).Error; err != nil {
		return merrors.E(op, merrors.DBError, err, merrors.ErrInternal)
	}
	return nil
}

// 查询进件申请
func (r *ApplymentRepo) QueryByApplyNo(_ context.Context, db *gorm.DB, applyNo string) (*model.Applyment, error) {
	const op merrors.Op = "ApplymentRepo.QueryByApplyNo"
	res := model.Applyment{}
	if err := db.Model(&model.Applyment{}).Where("apply_no = ?", applyNo).First(&res).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, merrors.E(op, merrors.NotExist, merrors.ErrNotFound, err)
		} else {
			return nil, merrors.E(op, merrors.DBError, merrors.ErrInternal, err)
		}
	}
	return &res, nil
}
